
#include "picshow.h"
#include "ui_picshow.h"

// 对于总是要把里面的一行 #include <picbutton.h> 改成 #include <./PicShow/picbutton.h>，是可以先关闭项目再打开项目的

#include <QGraphicsOpacityEffect>
#include <QPropertyAnimation>
#include <QEasingCurve>
#include <QPushButton>

#include "./PicShow/picbutton.h"

PicShow::PicShow(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::PicShow)
{
    ui->setupUi(this);

    // 设置 normal  hover  pressed 状态下的 QPushButton 按钮图片
    // D:\\qt-Project\\qt-project\\AlbumProject\\AlbumProject\\icon\\previous.png
    ui->previousBtn->SetIcons(":/icon/previous.png", ":/icon/previous_hover.png", ":/icon/previous_press.png");
    ui->nextBtn->SetIcons(":/icon/next.png", ":/icon/next_hover.png", ":/icon/next_press.png");
    // 去掉边框(在再 ui 界面的 Margin 什么的微调就可以变成圆形了)
    ui->previousBtn->setStyleSheet("QPushButton { border: 0px; }");
    ui->nextBtn->setStyleSheet("QPushButton { border: 0px; }");
    // ui->closeBtn->setStyleSheet("QPushButton { border: 0px; }");

    // 按钮的渐隐动画
    QGraphicsOpacityEffect* opacity_pre = new QGraphicsOpacityEffect(this);
    opacity_pre->setOpacity(0.3); // 设置透明度0.5,透明范围：[0,1]
    ui->previousBtn->setGraphicsEffect(opacity_pre); // 应用到需要透明变化的控件；

    QGraphicsOpacityEffect *opacity_next = new QGraphicsOpacityEffect(this);
    opacity_next->setOpacity(0.3); // 设置透明度0.5,透明范围：[0,1]
    ui->nextBtn->setGraphicsEffect(opacity_next); // 应用到需要透明变化的控件；

    // 使用属性动画类让控件在透明度范围内变化
    _animation_show_pre = new QPropertyAnimation(opacity_pre, "opacity", this);
    _animation_show_pre->setDuration(500); // 动效时长3s
    _animation_show_pre->setEasingCurve(QEasingCurve::Linear);

    _animation_show_next = new QPropertyAnimation(opacity_next, "opacity", this);
    _animation_show_next->setDuration(500); // 动效时长3s
    _animation_show_next->setEasingCurve(QEasingCurve::Linear);


    // 前进后退按钮切换图片
    // _picshow 界面的 QPushButton 点击的信号得传递到 _protree 界面的产生变化(也是为什么设置成双向链表)【_picshow 界面的 QPushButton 的 clicked 信号不能直接传给 _protree 界面】
    // 1. 因为点击 _picshow 界面的QPushButton: nextBtn 和 previousBtn，会触发对应的 clicked 点击信号，传递给 _picshow 对应的信号。
    // 2. _picshow 和 _protree 刚好都在 MainWindow 中，所以 _picshow 对应的信号再触发 _protree 的槽函数产生对应的变化即可。
    // 3. 因为 _picshow 界面不需要传递多余
    connect(ui->nextBtn, &QPushButton::clicked, this, &PicShow::SigNextClicked);
    connect(ui->previousBtn, &QPushButton::clicked, this, &PicShow::SigPreClicked);
}

PicShow::~PicShow()
{
    delete ui;
}

// 鼠标进入 picLayout 和离开 picLayout 区域的动画显示
bool PicShow::event(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::Enter:
        ShowPreNextBtns(true);
        break;
    case QEvent::Leave:
        ShowPreNextBtns(false);
        break;
    default:
        break;
    }

    return QDialog::event(event); // 继续调用基类的虚函数
}

// 按钮的渐隐动画，按钮的隐藏和显示
void PicShow::ShowPreNextBtns(bool b_show)
{
    // 设置动画从显示到隐藏
    if(b_show == false && b_btnvisible == true){
        _animation_show_pre->stop();
        // 设置动画从显示到隐藏
        _animation_show_pre->setStartValue(1);
        _animation_show_pre->setEndValue(0);
        _animation_show_pre->start();

        _animation_show_next->stop();
        // 设置动画从显示到隐藏
        _animation_show_next->setStartValue(1);
        _animation_show_next->setEndValue(0);
        _animation_show_next->start();

        b_btnvisible = false;

        return;
    }

    // 设置动画从隐藏到显示
    if(b_show == true && b_btnvisible == false){
        _animation_show_pre->stop();
        // 设置动画从隐藏到显示
        _animation_show_pre->setStartValue(0);
        _animation_show_pre->setEndValue(1);
        _animation_show_pre->start();

        _animation_show_next->stop();
        // 设置动画从隐藏到显示
        _animation_show_next->setStartValue(0);
        _animation_show_next->setEndValue(1);
        _animation_show_next->start();

        b_btnvisible = true;

        return;
    }
}

// proLayout(ProTree) 界面双击图片一路触发过来的槽函数 ---> picLayout(PicShow) 界面展示来显示
void PicShow::SlotSelectItem(const QString &path)
{
    _selected_path = path;
    _pix_map.load(path);
    auto width = this->width() - 20;
    auto height = this->height() - 20;
    _pix_map = _pix_map.scaled(width, height, Qt::KeepAspectRatio);
    ui->label->setPixmap(_pix_map); // 显示到 label 上
}

// 图像重绘
void PicShow::ReloadPic()
{
    if(_selected_path != ""){
        // 正确的或得 ui->gridLayout 的 width 和 height
        const auto& width = ui->gridLayout->geometry().width();
        const auto& height = ui->gridLayout->geometry().height();
        _pix_map.load(_selected_path);
        _pix_map = _pix_map.scaled(width, height, Qt::KeepAspectRatio);
        ui->label->setPixmap(_pix_map); // 显示到 label 上
    }
}

// 把处理好的，要显示的图片显示出来
void PicShow::SlotUpdatePic(const QString &currentPath)
{
    _selected_path = currentPath;
    if(_selected_path == "") return; // 为空的话，直接 return
    _pix_map.load(currentPath);
    // auto width = this->width() - 20;
    // auto height = this->height() - 20;
    const auto& width = ui->gridLayout->geometry().width();
    const auto& height = ui->gridLayout->geometry().height();
    _pix_map = _pix_map.scaled(width, height, Qt::KeepAspectRatio);
    ui->label->setPixmap(_pix_map); // 显示到 label 上
}

// 点击关闭的项目，正好是当前正在显示的项目 ---> 清空
void PicShow::SlotClearSelected()
{
    _selected_path = "";
}
